package com.dudu.controller;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;

import com.dudu.access.RedisUtil;
import com.dudu.bean.AccountBean;
import com.dudu.bean.AppExtendBean;
import com.dudu.enumeration.H5CodeDefinition;
import com.dudu.service.IAccountExtendService;
import com.dudu.service.IAppExtendService;
import com.dudu.service.IOperationPlatformCustAccountService;
import com.dudu.service.ISmsCodeService;
import com.dudu.service.impl.AccountExtendServiceImpl;
import com.dudu.service.impl.AppExtendServiceImpl;
import com.dudu.service.impl.OperationPlatformCustAccountServiceImpl;
import com.dudu.service.impl.SmsCodeServiceImpl;
import com.dudu.utils.DictionaryUtils;
import com.dudu.utils.Encrypt;
import com.dudu.utils.EnumUtility;
import com.dudu.utils.GuidUtil;
import com.dudu.utils.HtmlUtils;
import com.dudu.utils.HttpRequestInvocationHandler;
import com.dudu.utils.PhoneUtils;

import core.CoreService;
import net.sf.json.JSONObject;

/**
 * 网页回呼控制层实现
 * 
 * @author zx
 *
 */
public class PageCallbackController extends CoreService implements IPageCallbackController {

	/*
	 * 短信服务类
	 */
	private ISmsCodeService smsCodeServcie = new SmsCodeServiceImpl();

	/*
	 * 应用服务类
	 */
	private IAppExtendService appExtendService = new AppExtendServiceImpl();

	/*
	 * 账户服务类
	 */
	private IAccountExtendService accountExtendService = new AccountExtendServiceImpl();

	/*
	 * 运营平台服务类
	 */
	private IOperationPlatformCustAccountService opService = new OperationPlatformCustAccountServiceImpl();

	/*
	 * 用户前缀key 用于缓存全局唯一的用户访问uuid
	 */
	private static final String USER_PREFIX_KEY = "pcbuserid";

	/*
	 * 按钮默认颜色-红色
	 */
	private static final String DEFAULT_BUTTON_COLOR = "#FF0000";

	/*
	 * 默认展示方向
	 */
	private static final String DEFAULT_DIRECTION = "right";

	/*
	 * 默认位移，相对于浏览器边框
	 */
	private static final String DEFAULT_OFFSET = "0";

	/*
	 * 默认距底部距离，相对于浏览器边框
	 */
	private static final String DEFAULT_BOTTOM = "40";

	@Override
	public String getCode() {
		String callback = this.getRequest().getParameter("callback");
		JSONObject object = new JSONObject();
		String appid = this.getRequest().getParameter("appid");
		String phone = this.getRequest().getParameter("phone");
		// 校验手机号码是否非法
		if (PhoneUtils.isMobilePhone(phone) && StringUtils.isNotBlank(appid)) {
			String result = smsCodeServcie.sendCode(phone);
			if ("0".equals(result)) {
				object.put("result", "0");
				object.put("discripe", "验证码已发送，请注意查收");
			} else {
				object.put("result", "-1");
				object.put("discripe", "获取验证码失败，请重新获取");
			}
		} else {
			object.put("result", "-1");
			object.put("discripe", "参数错误");
		}
		String data = "";
		if (StringUtils.isNotBlank(callback)) {
			data = callback + "(" + object.toString() + ")";
		} else {
			data = object.toString();
		}
		return returnData(data);
	}

	/**
	 * 网页回呼插件入口
	 */
	@Override
	public String pageCallbackRouter() {
		String app_key = this.getRequest().getParameter("app_key");
		if (EnumUtility.isBlank(app_key)) {// 未传入应用标识
			return sendResponse(
					setParaMap(H5CodeDefinition.NULL_ACCOUNT.getCode(), H5CodeDefinition.NULL_ACCOUNT.getMessage()));
		}
		String cust_account = this.getRequest().getParameter("cust_account");
		if (EnumUtility.isBlank(cust_account)) {// 未传入账号标识
			return sendResponse(setParaMap(H5CodeDefinition.NULL_ORGACCOUNT.getCode(),
					H5CodeDefinition.NULL_ORGACCOUNT.getMessage()));
		}
		// 查询应用信息
		AppExtendBean appExtendBean = appExtendService.queryAppExtendByIdentify(app_key);
		if (EnumUtility.isBlank(appExtendBean)) {
			return sendResponse(setParaMap(H5CodeDefinition.NOT_EXISTS_APPACCOUNT.getCode(),
					H5CodeDefinition.NOT_EXISTS_APPACCOUNT.getMessage()));
		}
		// 根据账号cust_account查询账号信息
		AccountBean accountBean = accountExtendService.queryAccountDetailByCustAccount(cust_account);
		if (EnumUtility.isBlank(accountBean)) {
			return sendResponse(setParaMap(H5CodeDefinition.UNAVAILABLE_ORGACCOUNT.getCode(),
					H5CodeDefinition.UNAVAILABLE_ORGACCOUNT.getMessage()));
		}
		String callCode = this.getRequest().getParameter("callCode");
		if (EnumUtility.isBlank(callCode)) {
			return sendResponse(
					setParaMap(H5CodeDefinition.NULL_CALLCODE.getCode(), H5CodeDefinition.NULL_CALLCODE.getMessage()));
		}
		String callOrder = this.getRequest().getParameter("callOrder");
		if (EnumUtility.isBlank(callOrder)) {
			return sendResponse(setParaMap(H5CodeDefinition.NULL_CALLORDER.getCode(),
					H5CodeDefinition.NULL_CALLORDER.getMessage()));
		} else {
			if (!"caller".equals(callOrder) && !"called".equals(callOrder)) {
				return sendResponse(setParaMap(H5CodeDefinition.ILLEGAL_CALLORDER.getCode(),
						H5CodeDefinition.ILLEGAL_CALLORDER.getMessage()));
			}
		}
		String title = this.getRequest().getParameter("title");
		if (EnumUtility.isBlank(title)) {
			return sendResponse(
					setParaMap(H5CodeDefinition.NULL_TITLE.getCode(), H5CodeDefinition.NULL_TITLE.getMessage()));
		} else {
			try {
				title = new String(title.getBytes("iso-8859-1"), "utf-8");
			} catch (UnsupportedEncodingException e) {
				// ignore
			}
			if (title.length() > 10) {
				return sendResponse(setParaMap(H5CodeDefinition.OUTOFBOUNDS_TITLE_SIZE.getCode(),
						H5CodeDefinition.OUTOFBOUNDS_TITLE_SIZE.getMessage()));
			}
		}
		String content = this.getRequest().getParameter("content");
		if (EnumUtility.isBlank(content)) {
			return sendResponse(
					setParaMap(H5CodeDefinition.NULL_CONTENT.getCode(), H5CodeDefinition.NULL_CONTENT.getMessage()));
		} else {
			try {
				content = new String(content.getBytes("iso-8859-1"), "utf-8");
			} catch (UnsupportedEncodingException e) {
				// ignore
			}
			if (content.length() > 60) {
				return sendResponse(setParaMap(H5CodeDefinition.OUTOFBOUNDS_CONTENT_SIZE.getCode(),
						H5CodeDefinition.OUTOFBOUNDS_CONTENT_SIZE.getMessage()));
			}
		}
		String phones;
		String number = opService.getNumberByCallCode(callCode, app_key);
		if (StringUtils.isBlank(number)) {
			return sendResponse(setParaMap(H5CodeDefinition.INITDATA_ERROR.getCode(),
					H5CodeDefinition.INITDATA_ERROR.getMessage()));
		} else {
			phones = String.valueOf(number);
		}
		String display_mode = this.getRequest().getParameter("display_mode");
		if (EnumUtility.isBlank(display_mode)) {
			display_mode = "1";
		}
		String show = this.getRequest().getParameter("show");
		/*
		 * 如果没有传递参数show，默认为off，也就是需要点击按钮后才展示在线咨询页面
		 */
		if (StringUtils.isEmpty(show)) {
			show = "off";
		}
		String buttonColor = this.getRequest().getParameter("buttonColor");
		if (StringUtils.isEmpty(buttonColor)) {
			buttonColor = DEFAULT_BUTTON_COLOR;
		} else {
			if (!HtmlUtils.isHexadecimalColorValue(buttonColor)) {
				return sendResponse(setParaMap(H5CodeDefinition.ERROR_HEXCOLOR_VALUE.getCode(),
						H5CodeDefinition.ERROR_HEXCOLOR_VALUE.getMessage()));
			}
			buttonColor = "#" + buttonColor;
		}
		String offset = this.getRequest().getParameter("offset");
		if (StringUtils.isEmpty(offset)) {
			offset = DEFAULT_OFFSET;
		} else {
			try {
				int offset0 = Integer.parseInt(offset);
				if (offset0 < 0) {
					return sendResponse(setParaMap(H5CodeDefinition.NEGATIVE_OFFSET_ERROR.getCode(),
							H5CodeDefinition.NEGATIVE_OFFSET_ERROR.getMessage()));
				}
			} catch (NumberFormatException err) {
				return sendResponse(setParaMap(H5CodeDefinition.NAN_OFFSET_ERROR.getCode(),
						H5CodeDefinition.NAN_OFFSET_ERROR.getMessage()));
			}
		}
		String top = this.getRequest().getParameter("top");
		String bottom = "-1";
		if (StringUtils.isEmpty(top)) {
			bottom = DEFAULT_BOTTOM;
			top = "-1";
		}
		String direction = this.getRequest().getParameter("direction");
		if (StringUtils.isEmpty(direction)) {
			direction = DEFAULT_DIRECTION;
		}
		String requestTimeStamp = String.valueOf(new Date().getTime());
		String sign = Encrypt.sha1Encrypt(cust_account + accountBean.getKey_private() + requestTimeStamp);
		 String basepath = DictionaryUtils.getValueByTypeAndKey("common",
		 "domainUrl");
		Map<String, String> variables = new HashMap<String, String>();
		variables.put("app_key", app_key);
		variables.put("cust_account", cust_account);
		variables.put("phones", phones);
		variables.put("show", show);
		variables.put("title", title);
		variables.put("content", content);
		variables.put("callCode", callCode);
		variables.put("basepath", basepath);
		variables.put("buttonColor", buttonColor);
		variables.put("callOrder", callOrder);
		variables.put("display_mode", display_mode);
		variables.put("offset", offset);
		variables.put("top0", top);
		variables.put("bottom0", bottom);
		variables.put("direction0", direction);
		variables.put("timestamp", requestTimeStamp);
		variables.put("sign", sign);
		variables.put("uuid", GuidUtil.createGuid(USER_PREFIX_KEY));
		return sendResponse(variables);
	}

	/**
	 * 设置参数
	 * 
	 * @param code
	 * @param desc
	 * @return
	 */
	private Map<String, String> setParaMap(String code, String desc) {
		Map<String, String> result = new HashMap<String, String>();
		result.put("code", code);
		result.put("describe", desc);
		return result;
	}

	/**
	 * 返回响应结果，格式为js语句
	 * 
	 * @param variables
	 *            需要直接赋值的变量集合
	 * @return
	 */
	private String sendResponse(Map<String, String> variables) {
		 String script_url = DictionaryUtils.getValueByTypeAndKey("h5",
		 "pcbScriptUrl");
		// String script_url =
		// "http://localhost:8080/plugins/pcb/js/onlineTwonessCommunicate.js";
		return returnData(
				HtmlUtils.createAssignmentScript(variables) + HtmlUtils.importScript(new String[] { script_url }));
	}

	/**
	 * 校验验证码的正确性
	 * 
	 * @return
	 */
	@Override
	public String createTwonessCommunicate() {
		String callback = this.getRequest().getParameter("callback");
		String uuid = this.getRequest().getParameter("uuid");
		String keyCode = CaptchaAction.VALIDATE_CODE_KEY + uuid;
		String identifyingCode = RedisUtil.getString(keyCode);
		String randCode = this.getRequest().getParameter("randCode");
		JSONObject rc = new JSONObject();
		if (!randCode.equals(identifyingCode)) {
			rc.put("code", H5CodeDefinition.IDENTIFYINGCODE_NOT_MATCH.getCode());
			rc.put("describe", H5CodeDefinition.IDENTIFYINGCODE_NOT_MATCH.getMessage());
			RedisUtil.delKey(keyCode);
			return reponseResult(callback, rc);
		}
		String cust_account = this.getRequest().getParameter("cust_account");
		AccountBean accountBean = accountExtendService.queryAccountDetailByCustAccount(cust_account);
		if (EnumUtility.isBlank(accountBean)) {
			rc.put("code", H5CodeDefinition.UNAVAILABLE_ORGACCOUNT.getCode());
			rc.put("describe", H5CodeDefinition.UNAVAILABLE_ORGACCOUNT.getMessage());
			RedisUtil.delKey(keyCode);
			return reponseResult(callback, rc);
		}
		RedisUtil.delKey(keyCode);
		/*
		 * 直接调用两方通话接口
		 */
		IOpenAbilityDIALController dialController = new OpenAbilityDIALController();
		CoreService cs = (CoreService) dialController;
		InvocationHandler invocation = new HttpRequestInvocationHandler(this.getRequest());
		HttpServletRequest requestProxy = (HttpServletRequest) Proxy.newProxyInstance(
				this.getRequest().getClass().getClassLoader(), this.getRequest().getClass().getInterfaces(),
				invocation);
		cs.setRequest(requestProxy);
		cs.setResponse(this.getResponse());
		cs.setSession(this.getSession());
		cs.setDao(this.getDao());
		return dialController.dial();
	}

	/**
	 * 返回执行结果
	 * 
	 * @param callback
	 *            回调函数名字
	 * @param result
	 *            结果对象
	 * @return
	 */
	private String reponseResult(String callback, JSONObject result) {
		if (StringUtils.isEmpty(callback))
			return returnData(result.toString());
		else
			return returnData(callback + "(" + result.toString() + ")");
	}

	public static void main(String[] args) {
		String s = "-1";
		System.out.println(Integer.parseInt(s));
	}

}
